package com.sina.interfaces.manage.service.sys;


import com.sina.interfaces.core.exception.client.DataException;
import com.sina.interfaces.core.exception.server.ResourceExistsException;
import com.sina.interfaces.core.exception.server.UpdateException;
import com.sina.interfaces.core.util.*;
import com.sina.interfaces.domain.sys.Admin;
import com.sina.interfaces.domain.sys.Role;
import com.sina.interfaces.manage.dao.sys.AdminManageDao;
import com.sina.interfaces.manage.dao.sys.RoleManageDao;
import com.sina.interfaces.service.InterFacesDataSourceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import static com.sina.interfaces.service.ServiceConstant.INTERFACE_TX;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * 段浩杰   2017-10-30-12:44
 */
@Service("adminManageService")
public class AdminManageServiceImpl extends InterFacesDataSourceService implements AdminManageService {

    @Autowired
    @Qualifier("adminManageDao")
    private AdminManageDao adminManageDao;

    @Autowired
    @Qualifier("roleManageDao")
    private RoleManageDao roleManageDao;

    @Override
    @Transactional(readOnly = true, value = INTERFACE_TX, isolation = Isolation.READ_COMMITTED)
    public Admin getAdminByName(String name) {
        return adminManageDao.getAdminByName(name);
    }

    @Override
    @Transactional(readOnly = true, value = INTERFACE_TX, isolation = Isolation.READ_COMMITTED)
    public Admin getAdmin(String name) {
        return adminManageDao.getAdmin(name);
    }

    @Override
    @Transactional(readOnly = true, value = INTERFACE_TX, isolation = Isolation.READ_COMMITTED)
    public Admin getAdmin(Integer id) {
        return adminManageDao.get(Admin.class, id);
    }

    @Override
    @Transactional(value = INTERFACE_TX, isolation = Isolation.REPEATABLE_READ)
    public Admin updateAdmin(Admin admin) throws UpdateException, DataException {

        Admin a = adminManageDao.get(Admin.class, admin.getId());
        Assert.assertNotNull(a, "Admin[id=%s] not exists", admin.getId());

        try {
            a = updateAdminFiled(admin, a);
            adminManageDao.flush();

            return a;
        } catch (DataAccessException e) {
            LOG.error(" {} update Admin error.", Admin.class, e);
            throw new UpdateException(ResultCode.dataAccessError, e.getMessage(), e);
        }

    }

    /**
     * 所需要更新的字段的转换
     *
     * @param oldAdmin 前台传来的admin（瞬时态）
     * @param newAdmin 从数据库中查询的admin（持久态）
     * @return admin   最后要变为的admin（执行完update后变为游离态）
     */
    private Admin updateAdminFiled(Admin oldAdmin, Admin newAdmin) {


        /*根据是否为null来进行添加更新的字段*/
        if (!StringUtils.isEmpty(oldAdmin.getAddress())) {
            newAdmin.setAddress(oldAdmin.getAddress());
        }
        if (!StringUtils.isEmpty(oldAdmin.getEmail())) {
            newAdmin.setEmail(oldAdmin.getEmail());
        }
        if (!StringUtils.isEmpty(oldAdmin.getName())) {
            newAdmin.setName(oldAdmin.getName());
        }
        if (!StringUtils.isEmpty(oldAdmin.getPsd())) {
            newAdmin.setPsd(oldAdmin.getPsd());
        }
        if (oldAdmin.getStatus() != null) {
            newAdmin.setStatus(oldAdmin.getStatus());
        }
        if (!CollectionUtils.isEmpty(oldAdmin.getRoles())) {
            Set<Role> roles = getUpdateAdminAndRole(oldAdmin.getRoles());
            newAdmin.setRoles(roles);
        }
        return newAdmin;
    }

    /*关联表中所要更新的字段*/
    private Set<Role> getUpdateAdminAndRole(Set<Role> rols) {
        Set<Role> roles = new HashSet<>();
        Iterator<Role> iterator = rols.iterator();
        while (iterator.hasNext()) {
            Role role = iterator.next();
            if (role != null && role.getId() != null) {
                role = roleManageDao.get(Role.class, role.getId());
                roles.add(role);
            }
        }
        return roles;
    }

    @Override
    @Transactional(value = INTERFACE_TX, isolation = Isolation.READ_COMMITTED)
    public Admin saveAdmin(Admin admin) throws UpdateException, DataException {

        boolean exists;
        exists = adminManageDao.isExistsByUnique(Admin.class, "name", admin.getName());
        Assert.assertFalse(exists, ResourceExistsException.class, ResultCode.dataExists
                , "Admin[%s] exists", admin.getName());

        //把密码加密进行存储（md5摘要2次，不进行加盐，进行hex存储）
        String md5Psd = MD5Utils.getEncryptString("MD5", admin.getPsd(), null, 2, true);
        admin.setPsd(md5Psd);

        try {
            adminManageDao.save(admin);
            adminManageDao.flush();
            return admin;
        } catch (DataAccessException e) {
            LOG.error(" {} save Admin error.", Admin.class, e);
            throw new UpdateException(ResultCode.dataAccessError, e.getMessage(), e);
        }
    }

    @Override
    @Transactional(readOnly = true, value = INTERFACE_TX, isolation = Isolation.READ_COMMITTED)
    public List<Map<String, Object>> getAdminList(Admin admin, long[] count) {

        if (count != null && count.length > 0) {
            count[0] = adminManageDao.getAdminCount(admin);
        }

        return adminManageDao.getAdminList(admin);
    }

    @Override
    @Transactional(value = INTERFACE_TX, isolation = Isolation.REPEATABLE_READ)
    public int deleteAdmin(Integer id) throws UpdateException, DataException {

        Admin admin = get(Admin.class, id);
        Assert.assertNotNull(admin, "Admin[id=%s] not exists", admin.getId());

        try {
            return adminManageDao.deleteAdmin(id);
        } catch (DataAccessException e) {
            LOG.error(" {} delete Admin error.", Admin.class, e);
            throw new UpdateException(ResultCode.dataAccessError, e.getMessage(), e);
        }

    }


}
